package fan.project3_pksystem.Game;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import fan.project3_pksystem.Mapper.UserMapper;
import fan.project3_pksystem.Module.*;
import fan.project3_pksystem.WebSocket.WSResponse;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;

@Component
public class GameApi extends TextWebSocketHandler {
    @Autowired
    UserMapper userMapper;

    @Autowired
    GameRoomManager gameRoomManager;

    @Autowired
    private OnLinePlayers onlinePlayers;

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        UserInfo userInfo = (UserInfo) session.getAttributes().get("userInfo");
        if (userInfo.getUserName() == null) return;
        System.out.println("收到来自"+userInfo.getUserName()+"的"+message.getPayload());
//        玩家落子
        GameRoom room = gameRoomManager.getRoomByUserId(userInfo.getId());
        room.putChess(userInfo,message.getPayload());


    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {

        GameResponse gameResponse = new GameResponse();
        UserInfo userInfo = (UserInfo) session.getAttributes().get("userInfo");
        System.out.println(userInfo.getUserName()+"玩家进入房间页面 ");
//            处理多开问题
        if (userInfo.getUserName() == null) {
            gameResponse.setCode("ERROR");
            gameResponse.setMessage("用户未登录");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(gameResponse)));
            System.out.println("向 "+userInfo.getUserName()+" 发送"+gameResponse);
            return;
        }
//        用户未匹配成功
        if(gameRoomManager.getRoomByUserId(userInfo.getId())==null) {
            gameResponse.setCode("ERROR");
            gameResponse.setMessage("用户未匹配成功,不能进入房间");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(gameResponse)));
            System.out.println("向 "+userInfo.getUserName()+" 发送"+gameResponse);
            return;
        }
//        用户多开处理
        if(onlinePlayers.getGameOl(userInfo.getId())!=null || onlinePlayers.getHubOl(userInfo.getId())!=null) {
            gameResponse.setCode("ERROR");
            gameResponse.setMessage("禁止用户多开!!! 严重者将予以封号处理");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(gameResponse)));
            System.out.println("向 "+userInfo.getUserName()+" 发送"+gameResponse);
            return;
        }

//        正常加入游戏房间连接
        onlinePlayers.addGameOl(userInfo.getId(),session);
        GameRoom room = gameRoomManager.getRoomByUserId(userInfo.getId());
//        如果是第一个进入的晚间
        synchronized (room){
            if(room.getUser1()==null) {
                room.setUser1(userInfo);
            }else
//        如果是第二个玩家加入
                if(room.getUser2()==null) {
                    room.setUser2(userInfo);

//            通知双方已就位,准备开始游戏
                    notifyPlayers(room,room.getUser1(),room.getUser2());
                    notifyPlayers(room,room.getUser2(),room.getUser1());
                }else {
                    //        如果有第三者加入
                    gameResponse.setCode("ERROR");
                    gameResponse.setMessage("房间已满");
                    session.sendMessage(new TextMessage(objectMapper.writeValueAsString(gameResponse)));
                    System.out.println("向 "+userInfo.getUserName()+" 发送"+gameResponse);
                    return;
                }
        }




        gameResponse.setCode("SUCCESS");
        gameResponse.setMessage("进入游戏房间成功");
        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(gameResponse)));
        System.out.println(userInfo.getUserName()+"进入游戏房间:"+gameRoomManager.getRoomByUserId(userInfo.getId()).getRoomId());
//    到这里说明玩家正常进入房间了
        System.out.println("向 "+userInfo.getUserName()+" 发送"+gameResponse);

    }
    private void notifyPlayers(GameRoom room, UserInfo thisUser, UserInfo thatUser) throws IOException {
        GameStartResponse gameStartResponse = new GameStartResponse();
        gameStartResponse.setCode("SUCCESS");
        gameStartResponse.setMessage("gameStart");
        gameStartResponse.setThatUser(thatUser.getId());
        gameStartResponse.setThisUser(thisUser.getId());
        gameStartResponse.setIsWhite(room.getUser1().getId());
        onlinePlayers.getGameOl(thisUser.getId()).sendMessage(
                new TextMessage(objectMapper.writeValueAsString(gameStartResponse))
        );


    }


    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {


        UserInfo userInfo = (UserInfo) session.getAttributes().get("userInfo");
//  玩家掉线处理
        if(userInfo==null) {return;
        }else {
            if (gameRoomManager.getPlayerIsOnGame(userInfo.getId())) {
                GameRoom room = gameRoomManager.getRoomByUserId(userInfo.getId());
                if (room != null) {
                    if (room.getUser1().getId() == userInfo.getId()) {
                        room.setWinner(room.getUser2().getId());
                        userMapper.loserById(userInfo.getId());
                        userMapper.winnerById(room.getWinner());

                    } else {
                        room.setWinner(room.getUser1().getId());
                        userMapper.loserById(userInfo.getId());
                        userMapper.winnerById(room.getWinner());
                    }
                    GameResponse gameResponse = new GameResponse();
                    gameResponse.setCode("SUCCESS");
                    gameResponse.setWinnerId(room.getWinner());
                    gameResponse.setMessage("落子成功");
                    WebSocketSession winner = onlinePlayers.getGameOl(room.getWinner());
                    winner.sendMessage(new TextMessage(objectMapper.writeValueAsString(gameResponse)));


                    gameRoomManager.remove(room);

                }

            }
        }

        WebSocketSession session1 = onlinePlayers.getGameOl(userInfo.getId());
        if(session1!=null) {
            onlinePlayers.removeGameOl(userInfo.getId());
        }
        System.out.println(userInfo.getUserName()+"玩家离开游戏房间");
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        UserInfo userInfo = (UserInfo) session.getAttributes().get("userInfo");

        if(userInfo==null) {return;
        }else {
            GameRoom room = gameRoomManager.getRoomByUserId(userInfo.getId());
            if (room != null) {
                if(room.getUser1().getId()==userInfo.getId()) {
                    room.setWinner(room.getUser2().getId());
                    userMapper.loserById(userInfo.getId());
                    userMapper.winnerById(room.getWinner());

                }else {
                    room.setWinner(room.getUser1().getId());
                    userMapper.loserById(userInfo.getId());
                    userMapper.winnerById(room.getWinner());
                }
                GameResponse gameResponse = new GameResponse();
                gameResponse.setCode("SUCCESS");
                gameResponse.setMessage("落子成功");
                gameResponse.setWinnerId(room.getWinner());
                WebSocketSession winner = onlinePlayers.getGameOl(room.getWinner());
                winner.sendMessage(new TextMessage(objectMapper.writeValueAsString(gameResponse)));
                gameRoomManager.remove(room);

            }
        }


        WebSocketSession session1 = onlinePlayers.getGameOl(userInfo.getId());
        if(session1!=null) {
            onlinePlayers.removeGameOl(userInfo.getId());
        }
        System.out.println(userInfo.getUserName()+"玩家因异常离开游戏房间");
    }
}
